package com.atguigu.spzx.common.log.aspect;

import com.atguigu.spzx.common.log.annotation.Log;

import com.atguigu.spzx.common.log.service.SysOperLogService;
import com.atguigu.spzx.common.log.util.LogUtil;
import com.atguigu.spzx.model.entity.system.SysOperLog;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Aspect //声明一个切面类
@Component
@Slf4j
//@Order(value = -1)  //取值范围   Integer.MIN_VALUE   -  Integer.MAX_VALUE   值越小优先级越高
public class LogAspect {

    @Autowired
    SysOperLogService sysOperLogService;


    //定义通知方法,用的环绕通知。
    @Around(value = "@annotation(mylog)") //切入点表达式的含义：只要目标方法上标记了Log注解，就会执行环绕通知方法。
    public Object logAspect(ProceedingJoinPoint joinPoint, Log mylog){ //ProceedingJoinPoint就是目标方法

        SysOperLog sysOperLog = new SysOperLog();

        LogUtil.beforeHandleLog(mylog,joinPoint,sysOperLog); //执行目标方法前采集日志

        Object proceed = null;
        try {
            proceed = joinPoint.proceed();  //目标方法

            LogUtil.afterHandlLog(mylog,proceed,sysOperLog,0,"");
        } catch (Throwable e) {
            LogUtil.afterHandlLog(mylog,proceed,sysOperLog,1,e.getMessage());
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        } finally {
            sysOperLogService.save(sysOperLog);
        }

        return proceed;
    }

}
